package com.xudu.tourbackend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.xudu.tourbackend.common.globalEnum.ErrorCode;
import com.xudu.tourbackend.entity.Element;
import com.xudu.tourbackend.entity.Route;
import com.xudu.tourbackend.entity.Tag;
import com.xudu.tourbackend.entity.request.AddElementRequest;
import com.xudu.tourbackend.entity.request.SearchElementRequest;
import com.xudu.tourbackend.entity.request.UpdateElementRequest;
import com.xudu.tourbackend.exception.ServiceException;
import com.xudu.tourbackend.mapper.ElementMapper;
import com.xudu.tourbackend.mapper.TagMapper;
import com.xudu.tourbackend.service.IElementService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xudu.tourbackend.service.IRouteService;
import com.xudu.tourbackend.service.IUserService;
import com.xudu.tourbackend.utils.QiniuUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xudu
 * @since 2024-06-22
 */
@Service
public class ElementServiceImpl extends ServiceImpl<ElementMapper, Element> implements IElementService {

    @Resource
    private ElementMapper elementMapper;

    @Resource
    private TagMapper tagMapper;

    @Resource
    private IUserService userService;

    @Resource
    private QiniuUtil qiniuUtil;

    @Resource
    private IRouteService routeService;

    @Override
    public int addElement(AddElementRequest addElementRequest, HttpServletRequest request) {
        if (!userService.isAdmin(request)){
            throw new ServiceException(ErrorCode.NO_AUTH);
        }

        Element element = new Element();
        String elementName = addElementRequest.getElementName();
        if (StringUtils.isNotBlank(elementName)){
            element.setElementName(elementName);
        }
        MultipartFile elementImage = addElementRequest.getElementImage();
        if (elementImage != null){
            element.setElementImage(qiniuUtil.upload(elementImage));
        }

        Integer tagId = addElementRequest.getTagId();
        if (tagId != null) {
            Tag tag = tagMapper.selectById(tagId);
            if (tag == null){
                throw new ServiceException(ErrorCode.PARAMS_ERROR, "标签不存在");
            }
            element.setTagId(tagId);
        }

        boolean save = this.save(element);
        if (!save){
            throw new ServiceException(ErrorCode.SYSTEM_ERROR, "添加失败");
        }

        return element.getId();


    }

    @Override
    public Boolean updateElement(UpdateElementRequest updateElementRequest, HttpServletRequest request) {
        if (!userService.isAdmin(request)){
            throw new ServiceException(ErrorCode.NO_AUTH);
        }
        //获取更新请求参数
        Integer id = updateElementRequest.getId();
        if (id == null || id <= 0){
            throw new ServiceException(ErrorCode.PARAMS_ERROR);
        }
        //判断数据库中是否要有想要更新的数据
        Element elementdb = elementMapper.selectById(id);
        if (elementdb == null){
            throw new ServiceException(ErrorCode.PARAMS_ERROR, "请求更改数据不存在");
        }
        Element element = new Element();
        BeanUtils.copyProperties(updateElementRequest, element);
        MultipartFile elementImage = updateElementRequest.getElementImage();
        if (elementImage != null){
            qiniuUtil.deleteFile(elementdb.getElementImage());
            element.setElementImage(qiniuUtil.upload(elementImage));
        }

        boolean b = this.updateById(element);
        if (!b){
            throw new ServiceException(ErrorCode.SYSTEM_ERROR, "更新失败");
        }
        return true;

    }

    @Override
    @Transactional(rollbackFor = Exception.class) //操作多个数据库表的时候防止个别数据库表操作失败，一起成功或者一起失败
    public int deleteElement(List<Integer> ids, HttpServletRequest request) {
        if (!userService.isAdmin(request)){
            throw new ServiceException(ErrorCode.NO_AUTH);
        }
        for (Integer id : ids){
            if (id == null || id <= 0){
                throw new ServiceException(ErrorCode.PARAMS_ERROR);
            }

            //关联删除包含该元素的路线的元素信息
            List<Route> list = routeService.list();
            for (Route route : list){
                String elementId = route.getElementId();
                Gson gson = new Gson();
                List<Integer> elementList = gson.fromJson(elementId, new TypeToken<List<Integer>>() {}.getType());
                if (elementList.contains(id)){
                    elementList.remove(id);
                    String elementListString = gson.toJson(elementList);
                    route.setUpdateTime(null);
                    route.setElementId(elementListString);
                    routeService.updateById(route);
                }
            }
            
        }

        int i = elementMapper.deleteBatchIds(ids);
        if (i <= 0){
            throw new ServiceException(ErrorCode.SYSTEM_ERROR, "删除失败");
        }
        return i;
    }

    @Override
    public List<Element> searchElement(SearchElementRequest searchElementRequest, HttpServletRequest request) {
        if (!userService.isAdmin(request)){
            throw new ServiceException(ErrorCode.NO_AUTH);
        }
        QueryWrapper<Element> elementQueryWrapper = new QueryWrapper<>();
        Integer id = searchElementRequest.getId();
        if (id != null && id > 0){
            elementQueryWrapper.lambda().eq(Element::getId, id);
        }
        String elementName = searchElementRequest.getElementName();
        if (elementName != null){
            elementQueryWrapper.lambda().like(Element::getElementName, elementName);
        }
        Integer tagId = searchElementRequest.getTagId();
        if (tagId != null && tagId > 0){
            elementQueryWrapper.lambda().eq(Element::getTagId, tagId);
        }
        List<Element> list = this.list(elementQueryWrapper);
        if (list == null || list.isEmpty()){
            throw new ServiceException(ErrorCode.PARAMS_ERROR);
        }
        return list;

    }

    @Override
    public List<Element> searchElement(String elementName, HttpServletRequest request) {
        if (!userService.isAdmin(request)){
            return Collections.emptyList();
        }
        QueryWrapper<Element> queryWrapper = new QueryWrapper<>();
        if (elementName != null){
            queryWrapper.lambda().like(Element::getElementName, elementName);
        }
        List<Element> elements = elementMapper.selectList(queryWrapper);
        if (elements == null || elements.isEmpty()){
            return Collections.emptyList();
        }
        return elements;
    }

    @Override
    public List<Element> searchElement(int tagId) {
        if (tagId <= 0){
            return Collections.emptyList();
        }
        List<Element> elements = elementMapper.selectList(new QueryWrapper<Element>().lambda().eq(Element::getTagId, tagId));
        if (elements == null || elements.isEmpty()){
            return Collections.emptyList();
        }
        return elements;

    }
}
